﻿using System;

using System.Collections.Generic;
using System.Text;
using Silvermoon.Controls;
using Silvermoon.Controls.Interfaces;
using Silvermoon.Visuals;
using Silvermoon.Controls.Classes;
using Silvermoon.OpenGL;
using System.Drawing;
using System.Reflection;
using System.IO;

namespace FileExplorer
{
    public class StartMenuItem : ListViewItem, ILensItem  //,ILensItemImage
    {
        public const int ItemHeight = 84;

        public static FontSprite Font = new FontSprite(new System.Drawing.Font(FontFamily.GenericSansSerif, 18f, FontStyle.Regular));

        private string title = string.Empty;
        private Slider<StartMenuDetailChunk> slider;
        private ListViewItem lensItem;
        private StringVisual titleVisual;
        private int selectedIndex;

        public StartMenuItem()
            : base()
        {
            titleVisual = new StringVisual { Font = StartMenuItem.Font, Shadowed = true, Color = Color.White, LineAlignment = Alignment.Center, LineMode = LineMode.MultiLineEndElipsis };
            slider = new Slider<StartMenuDetailChunk> { Margin = new Margin(0) };
            lensItem = new ListViewItem();
            lensItem.Controls.Add(slider);
            Height = ItemHeight;
            ShowBorderLine = false;
            lensItem.ShowBorderLine = false;

        }

        /// <summary>
        /// StartMenuItem constructor to easily allow to create a complex StartMenuItem with several chunks with one single command.
        /// </summary>
        /// <param name="title">The title for the item.</param>
        /// <param name="chunks">A collection of <see cref="T:StartMenuDetailChunk"/>s.</param>
        public StartMenuItem(string title, params StartMenuDetailChunk[] chunks)
            : this()
        {
            this.Title = title;
            foreach (var chunk in chunks) Chunks.Add(chunk);
        }

        public StartMenuItem(string title, string imageResourcepath, params StartMenuDetailChunk[] chunks)
            : this(title, chunks)
        {
            AddImage(imageResourcepath);
        }


        public StartMenuItem(string title, string details, string imageResourcePath)
            : this(title, details)
        {
            AddImage(imageResourcePath);
        }


        /// <summary>
        /// StartMenuItem constructor to easily allow to create a complex StartMenuItem with several chunks with one single command.
        /// </summary>
        /// <param name="title">The title for the item.</param>
        /// <param name="details">The details for the first and only Chunk.</param>
        public StartMenuItem(string title, string details)
            : this()
        {
            this.Title = title;
            StartMenuDetailChunk chunk = new StartMenuDetailChunk { Title = title, Details = details };
            Chunks.Add(chunk);
            lensItem.Controls.Clear();
            chunk.Margin = new Margin(0);
            lensItem.Controls.Add(chunk);
            //Chunks.Add(new StartMenuDetailChunk());

        }

        private IEnumerable<Visual> GetBaseVisuals() { return base.Visuals; }

        /// <summary>
        /// We add our own Visuals here using yield pattern:
        /// </summary>
        public override IEnumerable<Visual> Visuals
        {
            get
            {
                foreach (Visual c in GetBaseVisuals()) yield return c;
                yield return titleVisual;
            }
            protected set { base.Visuals = value; }
        }

        public string Title { get { return title; } set { if (title != value) { title = value; Invalidate(InvalidationFlag.Text | InvalidationFlag.Appearance); } } }

        public IList<StartMenuDetailChunk> Chunks { get { return slider.Chunks; } }

        public int SelectedChunkIndex { get { return selectedIndex; } set { selectedIndex = value; } }

        public bool SingleChunkSelect { get { return slider.AutoStop; } set { slider.AutoStop = value; } }

        private void AddImage(string imageResourcePath)
        {
            Texture img = new Texture();

            {
                // add an image to the first chunk:
                Stream stream = Assembly.GetCallingAssembly().GetManifestResourceStream(imageResourcePath);
                if (stream == null) throw new ArgumentNullException("imageResourcePath");
                img.LoadFromStream(stream);
                Chunks[0].Image = img;
            }
        }


        protected override void OnLayout()
        {
            // other than controls, the bounds of Visuals must be scaled to fit on small and large displays. Control has various static helper methods for scaling and unscaling:
            titleVisual.Bounds = Control.Scale(ClientBounds);
            titleVisual.Text = title;
            base.OnLayout();
        }

        /// <summary>
        /// The item can be clicked by pressing the the enter key rather than tapping. In this case we must redirect the click event to the active chunk,
        /// but only when the item is already the selected item. Otherwise a click by tapping would also click the first chunk which is not intended:
        /// </summary>
        public override void OnClick()
        {
            if (ListView.SelectedItem == this)
            {
                if (Chunks.Count > 0) Chunks[0].OnClick();
            }

            base.OnClick();
        }


        #region ILensItem Members

        /// <summary>
        /// We return the lensItem here that becomes visible when this Item is inside the lens of the <see cref="T:LensView"/>.
        /// </summary>
        ItemBase ILensItem.LensItem { get { return lensItem; } }

        /// <summary>
        /// When the item gets into the lens, change it to show the first chunk:
        /// </summary>
        void ILensItem.AddedToLens()
        {
            slider.Offset = 0;
        }

        void ILensItem.RemovedFromLens()
        {
        }

        #endregion

        #region ILensItemImage Members

        public Texture LensImage
        {
            get { return Chunks.Count > 0 ? Chunks[0].Image : null; }
        }

        #endregion
    }
}
